#ifndef _EB0_PREREQ_H_
#define _EB0_PREREQ_H_

namespace EB0
{
	// Precision... (http://support.microsoft.com/kb/145889)
	#define EPSILON 0.0001   // Define your own tolerance.
	#define FLOAT_EQ(x,y) (((y - EPSILON) < x) && (x < (y + EPSILON)))

	// Math
	#define PI 3.14159
	#define DEG_TO_RAD PI / 180 // Multiply degrees by DEG_TO_RAD to get radians
	#define RAD_TO_DEG 180 / PI // Multiply radians by RAD_TO_DEG to get degrees

	// Defines
	#define WINDOW_ICON_PATH "graphics/EBicontrans.png"
	#define PAUSE_SCREEN_PATH "graphics/pause.png"
	#define TILE_SIZE 16 // 16 x 16 pixels

	// Classes
	namespace Managers
	{
		class AudioManager; // Singleton
		class ImageManager; // Singleton
		class StateManager; // attached to each window
		class TaskManager; // Singleton
	}

	namespace Window
	{
		class RenderWindow;
		class Layer;
		class FrameListener;
		class WindowListener;

		class DefaultWindowListener;
	}

	namespace Graphics
	{
		class Renderable;
	}

	namespace Entities
	{
		class Entity;
		class Player;
		class SeekBot;
	}

	namespace States
	{
		class GameState;

		class Slideshow;
		class TitleScreen;
		
		class World;
		class ThePlace;
		
		class Pause;
		
		//class Textbox;
	}

	namespace Tasks
	{
		class GameTask;

		// Examples ...
		//class Timer;
		//class Clock; // day and night
	}

	namespace Debug // System
	{
		class Exception;
		void ErrorLog(const char* error);
	}

	// Function prototypes and aliases
	void runGame();
	void initialize();
	void mainLoop();
	void handleWindowEvents();
	void runTick();
	void renderWindow(float dt = 0.0f);
	void shutdown();

	bool isRunning();
	void quit();

	clock_t getClock();

	void pushState(States::GameState* state);
	void popState();
	void popAllStates();
	void changeState(States::GameState* state);

	void addTask(Tasks::GameTask* task);
	void removeTask(Tasks::GameTask* task);
	void removeAllTasks();
}

#endif // _EB0_PREREQ_H_